#include "GameStateUpdate.h"

// GameEngine.
#include "Renderer.h"
#include "Binding.h"
#include "InputManager.h"
#include "Scene.h"
#include "Material.h"

// Renderer.
#include "Model.h"
#include "Camera.h"
#include "ShaderProgram.h"

// GLM.
#include <gtc/type_ptr.hpp>

lj::GameStateUpdate::GameStateUpdate()
	: GameState(eGameState_Update)
	, m_Visual(NULL)
{

}

lj::GameStateUpdate::~GameStateUpdate()
{

}

void lj::GameStateUpdate::Update()
{
	le::Renderer* renderer = le::Binding::GetInstance()->GetRenderer();
	renderer->Clear(1.f, 0.5f, 0.f, 1.f);
	renderer->MakeShaderActive(0);

	/* le::ShaderProgram* shaderProgram = renderer->GetShaderProgram(0);

	le::Camera* activeCam = renderer->GetActiveCamera();
	shaderProgram->SetShaderVariable("viewMatrix", glm::value_ptr(activeCam->GetViewMatrix()));
	shaderProgram->SetShaderVariable("projectionMatrix", glm::value_ptr(activeCam->GetProjectionMatrix()));*/

	le::Binding::GetInstance()->GetScene()->Render(renderer);

	renderer->Present();
}

void lj::GameStateUpdate::Init()
{
	le::Model* testModel = le::Binding::GetInstance()->GetRenderer()->CreateModel();

	le::Material* testMaterial = LeNew le::Material();
	testMaterial->LoadFromFile(le::Path("C:/Develop/LeJeux/LeProjects/LeJeux/Data/Resources/Materials/TestMaterial.xml"));

	m_Visual = LeNew le::Visual();
	m_Visual->AddModel(testModel);
	m_Visual->SetMaterial(testMaterial);

	le::Binding::GetInstance()->GetScene()->AttachVisual(m_Visual);

	le::Binding::GetInstance()->GetInputManager()->AddInputListener(this);
}

void lj::GameStateUpdate::Exit()
{
	le::Binding::GetInstance()->GetInputManager()->RemoveInputListener(this);
}

bool lj::GameStateUpdate::OnInputEvent( const SDL_Event& inputEvent )
{
	le::Camera* activeCam = le::Binding::GetInstance()->GetRenderer()->GetActiveCamera();
	switch (inputEvent.key.keysym.sym)
	{
	case  SDLK_w:
		activeCam->SetPosition(activeCam->GetPosition() + activeCam->GetLookat() * 0.1f);
		break;
	case  SDLK_s:
		activeCam->SetPosition(activeCam->GetPosition() + activeCam->GetLookat() * -0.1f);
		break;
	case  SDLK_a:
		activeCam->SetPosition(activeCam->GetPosition() + activeCam->GetRight() * 0.1f);
		activeCam->SetLookat(activeCam->GetLookat() + activeCam->GetRight() * 0.1f);
		break;
	case  SDLK_d:
		activeCam->SetPosition(activeCam->GetPosition() + activeCam->GetRight() * -0.1f);
		activeCam->SetLookat(activeCam->GetLookat() + activeCam->GetRight() * -0.1f);
		break;
	}
	return false;
}
